PersonalizeのAutoML機能を使ったレシピの自動選択を試してみた
Personalizeでは過去のユーザの行動によるアイテムとのインタラクションデータを元にしたレコメンドが可能です。
ソリューションを作成するにあたり、データや目的に応じたレシピを選択する必要がありますが、AutoMLを用いることでデータに応じて適切なUSER_PERSONALIZATION
用のレシピを自動的に選択してくれます。今回はこのAutoML機能を試してみます。
やってみる
コールドスタート用のサンプルノートブックで作成したデータセットグループとデータセットをそのまま用いて、AutoML機能を試してみます。
- データセット: MovieLens 1M Dataset | GroupLens
- スキーマ
- Interactions: USER_ID, ITEM_ID, EVENT_VALUE, TIMESTAMP, EVENT_TYPE
- Items: ITEM_ID, GENRE
- 対象レシピ: HRNN-Coldstart
- やること
- ソリューション作成
- ソリューションバージョン作成
- ソリューションやソリューションバージョンの結果の確認
ソリューション作成
まずはライブラリ/モジュールを読み込み、作成済みのデータセットグループのARNを指定します。
import boto3 import pandas as pd personalize = boto3.Session().client('personalize') dataset_group_arn = 'arn:aws:personalize:ap-northeast-1:123456789:dataset-group/DEMO-temporal-metadata-dataset-group-15107' # データセット等がすでに作成ずみのデータセットグループ
AutoMLを有効化し、対象のレシピと用いる評価指標を指定して、ソリューションを作成します。
対象のレシピを指定しない場合にはHRNN
が指定されます。評価指標を指定しない場合はprecision_at_25
が指定されます。
今回は対象レシピとしてHRNN
とHRNN-Metadata
、HRNN-Coldstart
を指定し、評価指標としてnormalized_discounted_cumulative_gain_at_5
を指定します。
response = personalize.create_solution( name='automl-test', datasetGroupArn=dataset_group_arn, performAutoML=True, event_type='' solutionConfig={ 'autoMLConfig': { 'metricName': 'normalized_discounted_cumulative_gain_at_5', 'recipeList': [ 'arn:aws:personalize:::recipe/aws-hrnn', 'arn:aws:personalize:::recipe/aws-hrnn-coldstart', 'arn:aws:personalize:::recipe/aws-hrnn-metadata' ] } } ) solution_arn = response['solutionArn']
マネジメントコンソールの場合
マネジメントコンソールからもAutoMLを用いたソリューションを作成できます。マネジメントコンソールの場合、比較対象のレシピとしてHRNN-Coldstart
は選択することができないようです。評価指標も選択できないため、自動的にprecision_at_25
が用いられます。
ソリューションバージョン作成
ソリューションバージョンを作成します。ソリューションバージョンを1つ作成することで、元となるソリューションバージョンと指定したレシピそれぞれのソリューションバージョンが自動的に作成されます。レシピごとのソリューションバージョンでは、自動的にハイパーパラメータ最適化(HPO)が実行されます。
response = personalize.create_solution_version( solutionArn=solution_arn )
今回の場合だと一時間ちょっとくらいでジョブが完了しました。
結果の確認
ジョブが完了したら、ソリューションやソリューションバージョンの情報を確認してみます。 まずは、ソリューションについて確認してみます。
personalize.describe_solution(solutionArn=solution_arn)
autoMLResult
にautoMLの結果、最も良かったレシピが記載されています。今回の場合だと、HRNN
になっています。
続いて、各ソリューションバージョンとそれぞれの評価指標を確認します。
solution_versions = personalize.list_solution_versions(solutionArn=solution_arn)['solutionVersions'] solution_versions = sorted(solution_versions, key=lambda x: x['creationDateTime']) solution_version_arns = [x['solutionVersionArn'] for x in solution_versions] metrics_data = {} solution_versions_data = {} for solution_version_arn in solution_version_arns: version = solution_version_arn.split('/')[-1] solution_version = personalize.describe_solution_version(solutionVersionArn=solution_version_arn)['solutionVersion'] solution_versions_data[version] = solution_version recipe = solution_version['recipeArn'].split('/')[-1] response = personalize.get_solution_metrics(solutionVersionArn=solution_version_arn) metrics_data[recipe] = response['metrics'] solution_versions_df = pd.DataFrame.from_dict(solution_versions_data, orient='index') metrics_df = pd.DataFrame.from_dict(metrics_data, orient='index')
評価指標をみてみます。
metrics_df
多くの指標においてHRNN
が最も高く、HRNN-Coldstart
が最も低くなっています。HRNN-Coldstart
が他と比べて圧倒的に低くなっているのは、ユーザとのインタラクション数が少ないコールドアイテムをレコメンドに含めようとする、レシピの特性によるものだと思われます。
各ソリューションバージョンを確認します。
solution_versions_df = pd.DataFrame.from_dict(solution_versions_data, orient='index')
1つのソリューションバージョンにはソリューション情報が記載されており、それ以外のソリューションバージョンにはソリューション情報が記載されていません。これはAutoMLジョブの元となるソリューションバージョンと実際に各レシピに基づいてHPOを実行するソリューションバージョンの違いだと思われます。
この元となるソリューションバージョンは各レシピのソリューションバージョンの内、最も評価指標が良かったものへのエイリアスになっているようです。今回の場合だと、HRNN
レシピの評価指標が良かったため、recipeArn
としてHRNN
が指定されています。
また、学習に要した時間も記載されています。今回は38.16時間のようです。0.24 * 38.16 = 9.1584
なので、およそ9ドルの費用がかかったことが分かります。
実際にかかった時間と差異がありますが、これは各ソリューションバージョン内で、HPOのために並列でジョブを実行しているためだと思われます。
さいごに
PersonalizeのAutoMLを試してみた内容を紹介しました。AutoMLによってデータセットに合ったレシピを知ることができ、尚且つハイパーパラメータが最適化されたソリューションバージョンも作成できます。並列実行によって、普通のレシピ実行時と大差ない実行時間で最適化されたソリューションバージョンを作成し、そのままリアルタイムレコメンドやバッチレコメンドに利用できるのは便利そうです。ただし、データセットを更新し、同じソリューションでソリューションバージョンを再作成した場合でも、指定してある各レシピに対してHPOが実行されるため、費用面で注意が必要です。また、最適化されたハイパーパラメータがどのような値かは確認できないため、その結果をもとにソリューションを作成するといったことは現在のところできなさそうです。
- 最適化されたハイパーパラメータの値を確認できるようになりました!(2020/3/24追記)